package com.yhs.YShop.config;

import java.io.IOException;

import org.elasticsearch.client.Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.elasticsearch.core.DefaultResultMapper;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.EntityMapper;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.yhs.YShop.elastice.repository",includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchRepository.class))
public class ElasticsearchConfiguration {

	@Bean
	public ElasticsearchTemplate elasticsearchTemplate(Client client,
			Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) {
		MappingElasticsearchConverter converter = new MappingElasticsearchConverter(
				new SimpleElasticsearchMappingContext());
		DefaultResultMapper mapper = new DefaultResultMapper(converter.getMappingContext(),
				new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).build()));
		return new ElasticsearchTemplate(client, converter, mapper);
	}

	public class CustomEntityMapper implements EntityMapper {

		private ObjectMapper objectMapper;

		public CustomEntityMapper(ObjectMapper objectMapper) {
			this.objectMapper = objectMapper;
			objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
		}

		public String mapToString(Object object) throws IOException {
			return objectMapper.writeValueAsString(object);
		}

		public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
			return objectMapper.readValue(source, clazz);
		}

	}
}
